package com.platform.utils;

import cn.hutool.extra.qrcode.BufferedImageLuminanceSource;
import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.ibatis.javassist.NotFoundException;
import org.springframework.util.Base64Utils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class QrCodeUtils {

    private static final int QUIET_ZONE_SIZE = 4;

//    /**
//     * 读取二维码中的内容, 并返回
//     *
//     * @param qrcodeImg 二维码图片的地址
//     * @return 返回二维码的内容
//     * @throws IOException       读取二维码失败
//     * @throws FormatException   二维码解析失败
//     * @throws ChecksumException
//     * @throws NotFoundException
//     */
//    public static String decode(String qrcodeImg) throws IOException, FormatException, ChecksumException, NotFoundException, com.google.zxing.NotFoundException {
//        BufferedImage image = ImageUtil.getImageByPath(qrcodeImg);
//        return decode(image);
//    }


    public static String decode(BufferedImage image) throws FormatException, ChecksumException, NotFoundException, com.google.zxing.NotFoundException {
        if (image == null) {
            throw new IllegalStateException("can not load qrCode!");
        }

        LuminanceSource source = new BufferedImageLuminanceSource(image);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
        QRCodeReader qrCodeReader = new QRCodeReader();
        Result result = qrCodeReader.decode(bitmap);
        return result.getText();
    }

    public static String decodeFromBase64(String base64Image) throws IOException, FormatException, ChecksumException, NotFoundException, com.google.zxing.NotFoundException {
        // Decode the base64 string to a byte array
        byte[] imageBytes = Base64.getDecoder().decode(base64Image);

        // Convert the byte array to a BufferedImage
        ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes);
        BufferedImage image = ImageIO.read(bis);

        // Use the decode method to extract the text from the QR code
        return decode(image);
    }

    public static String generateQRCodeBase64(String msg, int width, int height) throws WriterException, IOException {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.MARGIN, 1); // Set margin size

        // 生成二维码
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode(msg, BarcodeFormat.QR_CODE, width, height, hints);

        // 将二维码写入字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "png", outputStream);

//        BitMatrix bitMatrix = encode(msg, width, height, hints);
//        BufferedImage image = toBufferedImage(bitMatrix);

//        ByteArrayOutputStream baos = new ByteArrayOutputStream();

//        ImageIO.write(image, "png", baos);
//        byte[] bytes = baos.toByteArray();
        byte[] bytes = outputStream.toByteArray();
        System.out.println(bytes.length);
//        return Base64.getEncoder().encodeToString(bytes);
        return Base64Utils.encodeToString(bytes);
    }

    public static BufferedImage toBufferedImage(BitMatrix matrix) {
        return MatrixToImageWriter.toBufferedImage(matrix);
    }


    public static BitMatrix encode(String msg, int width, int height, Map<EncodeHintType, Object> hints) throws WriterException {
        ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;
        int quietZone = 1;

        if (hints != null) {
            if (hints.containsKey(EncodeHintType.ERROR_CORRECTION)) {
                errorCorrectionLevel = ErrorCorrectionLevel.valueOf(hints.get(EncodeHintType.ERROR_CORRECTION).toString());
            }
            if (hints.containsKey(EncodeHintType.MARGIN)) {
                quietZone = Integer.parseInt(hints.get(EncodeHintType.MARGIN).toString());
            }

            if (quietZone > QUIET_ZONE_SIZE) {
                quietZone = QUIET_ZONE_SIZE;
            } else if (quietZone < 0) {
                quietZone = 0;
            }
        }

        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode(msg, BarcodeFormat.QR_CODE, width, height, hints);
        return bitMatrix;
    }

}